/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package me.zhengjie.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import me.zhengjie.modbusTCP.EntranceTCP;
import me.zhengjie.pojo.Request;
import me.zhengjie.pojo.Response;
import me.zhengjie.pojo.sqlServer.*;
import me.zhengjie.ppService.*;
import me.zhengjie.repository.*;
import me.zhengjie.service.PPOutboundOrderService;
import me.zhengjie.service.PPStorageService;
import me.zhengjie.service.PPTaskResultService;
import me.zhengjie.service.dto.PPTaskResultDto;
import me.zhengjie.service.dto.PPTaskResultQueryCriteria;
import me.zhengjie.service.mapper.PPTaskResultMapper;
import me.zhengjie.util.UniqueCodeUtil;
import me.zhengjie.utils.*;
import me.zhengjie.wcs.PPWcsReport;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xinglin
 * @website https://eladmin.vip
 * @description 服务实现
 * @date 2024-08-03
 **/
@Service
@RequiredArgsConstructor
public class PPTaskResultServiceImpl implements PPTaskResultService {

    private final PPTaskResultRepository ppTaskResultRepository;
    private final PPTaskResultMapper ppTaskResultMapper;
    private final PPWcsReport ppWcsReport;
    private final PPStorageService ppStorageService;
    private final PPStationService ppStationService;
    private final PpPalletRepository ppPalletRepository;

    private final PPInventoryService ppInventoryService;

    private final PPMoveMissionRepository ppMoveMissionRepository;

    private final PPInventoryRepository ppInventoryRepository;

    private final PPStationRepository ppStationRepository;




    @Override
    public PageResult<PPTaskResultDto> queryAll(PPTaskResultQueryCriteria criteria, Pageable pageable) {
        Page<PPTaskResult> page = ppTaskResultRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        return PageUtil.toPage(page.map(ppTaskResultMapper::toDto));
    }

    @Override
    public List<PPTaskResultDto> queryAll(PPTaskResultQueryCriteria criteria) {
        return ppTaskResultMapper.toDto(ppTaskResultRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder)));
    }

    @Override
    @Transactional
    public PPTaskResultDto findById(Integer id) {
        PPTaskResult ppTaskResult = ppTaskResultRepository.findById(id).orElseGet(PPTaskResult::new);
        ValidationUtil.isNull(ppTaskResult.getId(), "PpTaskResult", "id", id);
        return ppTaskResultMapper.toDto(ppTaskResult);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(PPTaskResult resources) {
        ppTaskResultRepository.save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(PPTaskResult resources) {
        PPTaskResult ppTaskResult = ppTaskResultRepository.findById(resources.getId()).orElseGet(PPTaskResult::new);
        ValidationUtil.isNull(ppTaskResult.getId(), "PpTaskResult", "id", resources.getId());
        ppTaskResult.copy(resources);
        ppTaskResultRepository.save(ppTaskResult);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            ppTaskResultRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<PPTaskResultDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (PPTaskResultDto ppTaskResult : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("任务id", ppTaskResult.getWmsTaskId());
            map.put("任务类型", ppTaskResult.getWcsTaskType());
            map.put("容器编码", ppTaskResult.getLpnCode());
            map.put("实际取货地址", ppTaskResult.getFromLocation());
            map.put("实际送货地址", ppTaskResult.getToLocation());
            map.put("实际完成时间", ppTaskResult.getCreated());
            map.put("任务状态", ppTaskResult.getStatus());
            map.put("错误代码", ppTaskResult.getIssueCode());
            map.put("异常原因", ppTaskResult.getMessage());
            map.put("最后更新时间", ppTaskResult.getLastUpdated());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }


    //强制结束任务
    @Override
    @Transactional
    public void forceEnd(String id) {

        PPTaskResult ppTaskResult = ppTaskResultRepository.findPPTaskResultByWmsTaskId(id);
        if (ObjectUtil.isEmpty(ppTaskResult)) {
            throw new RuntimeException("任务不存在");
        }

        Request request = new Request();
        request.setMessageId(UniqueCodeUtil.createCode());
        //时间戳
        request.setMessageTime(new Timestamp(System.currentTimeMillis()).toString());

        if (ppTaskResult.getStatus()==0) {
            ppTaskResult.setStatus(1);
            request.setData(ppTaskResult);
            ppWcsReport.getTaskResult(request);

            ppTaskResult.setStatus(2);
            request.setData(ppTaskResult);
            ppWcsReport.doTaskResult(ppTaskResult);
        }


        if (ppTaskResult.getStatus()==1) {

            //强制结束
            ppTaskResult.setStatus(2);
            request.setData(ppTaskResult);
            ppWcsReport.doTaskResult(ppTaskResult);
        }



    }


    //删除任务
    @Override
    @Transactional
    public void deleteTask(Integer id) {
        PPTaskResult ppTaskResult = ppTaskResultRepository.findById(id).orElse(null);
        if (ObjectUtil.isEmpty(ppTaskResult)) {
            throw new RuntimeException("任务不存在");
        }

        Integer taskType = ppTaskResult.getWcsTaskType();
        // 入库任务
        if (taskType == 1) {
            //Status,0-初始 1-取货完成 2-任务完成（放货完成）3-异常
            //释放站点
            ppStationService.refeaseStation(ppTaskResult.getFromLocation());

            //释放储位
            String storageCode = ppTaskResult.getToLocation();
            ppStorageService.openStorage(storageCode);


        } else if (taskType == 2) {
            PPStation ppStation = ppStationRepository.findByStationCode(ppTaskResult.getToLocation());
            //释放工作站
            ppStationRepository.refeaseStation(ppStation.getStationCode());

            //出库取消禁用储位
            ppStorageService.openStorage(ppTaskResult.getFromLocation());

            //更新库存状态
            PPInventory ppInventory = ppInventoryRepository.findPPInventoryByStorageCode(ppTaskResult.getFromLocation());
            ppInventoryService.refeaseInventory(ppInventory);

            //移库任务
        } else if (taskType == 3) {

            //更新库存状态
            PPInventory ppInventory = ppInventoryRepository.findPPInventoryByStorageCode(ppTaskResult.getFromLocation());
            ppInventoryService.refeaseInventory(ppInventory);


            //移库任务完成后，取消禁用储位
            ppStorageService.openStorage(ppTaskResult.getToLocation());
            ppStorageService.openStorage(ppTaskResult.getFromLocation());


            //删除移库任务
            ppMoveMissionRepository.deletePPMoveMissionByMissionCode(ppTaskResult.getWmsTaskId());
        }
    }


}
